﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using Network;
using Network.Messages.LiveControl;
using static Providers.LiveControl.Server.WindowApi;

namespace Providers.LiveControl.Server.ScreenHelper
{
    public class GridNodeTree
    {
        private int[] _oldBitmapInts = null;
        private Bitmap _bitmap = null;
        private readonly RectGridNode _nodeRoot;
        private readonly int _screenIndex;
        private int test = 100;
        private int _sendFrameIndex = 0;
        public GridNodeTree(int index)
        {
            Queue<int> tQueue = new Queue<int>();
            tQueue.Enqueue(9);
            tQueue.Enqueue(4);
            //tQueue.Enqueue(2);
            //tQueue.Enqueue(2);
            _nodeRoot = new RectGridNode(tQueue, 0, 0);
            _screenIndex = index;
        }
        private Bitmap CopyFromScreen(int sourceX, int sourceY, int destinationX, int destinationY, Size blockRegionSize)
        {
            IntPtr hDesk = GetDesktopWindow();
            IntPtr hSrce = GetWindowDC(hDesk);
            IntPtr hDest = CreateCompatibleDC(hSrce);
            IntPtr hBmp = CreateCompatibleBitmap(hSrce, blockRegionSize.Width, blockRegionSize.Height);
            IntPtr hOldBmp = SelectObject(hDest, hBmp);
            bool b = BitBlt(hDest, destinationX, destinationY, blockRegionSize.Width, blockRegionSize.Height, hSrce, sourceX, sourceY, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
            Bitmap bmp = Image.FromHbitmap(hBmp);
            SelectObject(hDest, hOldBmp);
            DeleteObject(hBmp);
            DeleteDC(hDest);
            ReleaseDC(hDesk, hSrce);
            return bmp;
        }

        public void RequestNewScreen()
        {
            Screen tScreen = Screen.AllScreens[_screenIndex];
            Rectangle tRectangle = tScreen.Bounds;
            int offsetx = tRectangle.X;
            int offsety = tRectangle.Y;
            tRectangle.X = 0;
            tRectangle.Y = 0;
            _nodeRoot.SetRect(tRectangle, offsetx, offsety);

            Bitmap tempShot = CopyFromScreen(tScreen.Bounds.X, tScreen.Bounds.Y, 0, 0, new Size(tScreen.Bounds.Width, tScreen.Bounds.Height));
            bool[,] tempBools = new bool[test, test];

            Stopwatch t = Stopwatch.StartNew();
            TempParam tParam;
            tParam.OldScreen = _oldBitmapInts;
            tParam.Screen = PixelGrabber.GrabFullPixels(tempShot);

            Console.WriteLine("Screen capture done in: " + t.ElapsedMilliseconds + "ms");

            tParam.Scan = tempShot.Width;
            tParam.Bools = tempBools;
            Console.WriteLine($"tempShot.Width:{tempShot.Width}");
            _nodeRoot.CompareChange(tParam);
            t.Stop();
            Console.WriteLine("Screen capture done in: " + t.ElapsedMilliseconds + "ms");
            //Test(tempBools);

            _bitmap?.Dispose();
            _bitmap = tempShot;
            _oldBitmapInts = tParam.Screen;
        }

        private void Test(bool[,] tempBools)
        {
            for (int i = 0; i < test; i++)
            {
                for (int j = 0; j < test; j++)
                {
                    string inttemp = tempBools[i, j] ? "X" : "_";
                    Console.Write(inttemp);
                }
                Console.WriteLine();
            }
        }

        public void SendScreenInnerLoop(NetworkPeer network,
            List<MessageEventArgs<RequestScreenshotMessage>> dicMessages)
        {
            List<ClientRequestParam> paramList = new List<ClientRequestParam>();
            foreach (var messageEventArgse in dicMessages)
            {
                if (!_nodeRoot.Changed && !messageEventArgse.Message.FlagFirstFrame)
                {
                    _nodeRoot.SendEmpty(network, messageEventArgse.Connection);
                    continue;
                }
                ClientRequestParam tParam = new ClientRequestParam(messageEventArgse);
                tParam.GetRectAndSend(network);
                paramList.Add(tParam);

            }

            _nodeRoot.SendBitmap(_sendFrameIndex++, _bitmap, network, paramList);

            foreach (var clientRequestParam in paramList)
            {
                if (clientRequestParam.Message.FlagFirstFrame)
                {
                    clientRequestParam.Message.Resolve = true;
                }
            }
        }

    }
}
